global !p
from snippet_helpers import *
endglobal

snippet v "var/let/const" w
${1:const} ${2:name} = ${VISUAL}$3;$0
endsnippet

snippet if "if" b
if (${1}) {
	${2:${VISUAL}}
}$0
endsnippet

snippet el "else"
else {
	${1:${VISUAL}}
}$0
endsnippet

snippet eif "else if"
else if (${1}) {
	${2:${VISUAL}}
}$0
endsnippet

snippet cl "console.log(...)"
console.log('$1: ', $1)$0
endsnippet

snippet lg "console.log"
(console.log('${1:${VISUAL}}', ${2:${VISUAL}}), ${VISUAL})$0
endsnippet

snippet ca "console.assert(...)" b
console.assert($1, '$2')$0
endsnippet

snippet :f "Object Method"
${1:method_name}: function(${3:attribute}) {
	${VISUAL}$0
}${10:,}
endsnippet

snippet fun "function (fun)" i
function ${1:function_name}(${2:argument}) {
	${VISUAL}$0
}
endsnippet

snippet fn "Anonymous Function" i
function($1) {
	${VISUAL}$0
}
endsnippet

snippet > "Arrow Function" w
($1) => {
	${VISUAL}$0
}
endsnippet

snippet ed "export default" b
export default ${1:`!p snip.rv = path_to_component_name(path, pascal_case_basename)`}$0
endsnippet

snippet im "import" b
import ${2:`!p snip.rv = formatImportedName(t[1], False)`} from '${1}';
endsnippet

snippet de "Debugger" wi
debugger;
endsnippet

snippet for "for (...) {...} (counting down, faster)" b
for (let ${2:i} = ${1:array}.length - 1; $2 >= 0; --$2) {
	${VISUAL}$0
}
endsnippet

snippet re "require" b
const `!p snip.rv = formatImportedName(t[1])` = require('${1}');$0
endsnippet

snippet todo "Tag TODO" b
// TODO: $0
endsnippet

snippet fixme "Tag FIXME" b
// FIXME: $0
endsnippet

snippet xxx "Tag XXX" b
// XXX: $0
endsnippet

###########
#  JSDoc  #
###########

snippet func "function with dynamic docblock" b
`!p
# Currently Ultisnips does not support dynamic tabstops, so we cannot add
# tabstops to the datatype for these param tags until that feature is added.
def formatTag(argument):
	return " * @param {{}} {0}".format(argument)

arguments = t[2].split(',')
arguments = [argument.strip() for argument in arguments if argument]

if len(arguments):
	tags = map(formatTag, arguments)
	snip.rv = "/**"
	for tag in tags:
		snip += tag
	snip += ' */'
	snip += ''
else:
	snip.rv = ''
`${1}(${2}) {
	${0:${VISUAL}}
},
endsnippet

##########
#  Node  #
##########

snippet me "module.exports" b
module.exports = ${1:`!p snip.rv = path_to_component_name(path, pascal_case_basename)`};$0
endsnippet

#########
#  JSX  #
#########

snippet "<(\w+)>" "<Component>" rA
<`!p snip.rv = match.group(1)`$1>
	${2:${VISUAL}}
</`!p snip.rv = match.group(1)`>$0
endsnippet

snippet <> "React.Fragment" bA
<>
	${VISUAL}$0
</>
endsnippet

###########
#  React  #
###########

snippet ir "React Import(Both React and PureComponent)"
import React${1:, { $2 }} from 'react';
${3:import PropTypes from 'prop-types';}$0
endsnippet

snippet rc "React:Class [skeleton]"
class ${1:`!p snip.rv = path_to_component_name(path, pascal_case_basename)`} extends ${2:Component} {
	render() {
		return (
			${VISUAL}$0
		)
	}
}
endsnippet

snippet rfc "React functional component [skeleton]"
import React from 'react';

const ${1:`!p snip.rv = path_to_component_name(path, pascal_case_basename)`} = ({$2}) => (
	<div>
		$3
	</div>
);
$4
endsnippet

snippet rcon "React:constructor"
constructor(props) {
	super(props)

	this.state = {
		${VISUAL}$0
	}
}
endsnippet

snippet pt "React:propTypes"
static propTypes = {
	${VISUAL}$0
}
endsnippet

snippet pts "PropTypes" w
$1: PropTypes.$2`!p snip.rv=complete(t[2], ['array', 'bool', 'func', 'number', 'object', 'string', 'node', 'element', 'instanceOf', 'oneOf([])', 'oneOfType([])', 'arrayOf()', 'objectOf()', 'shape({})', 'any'])`,$0
endsnippet

snippet state "React Component state"
const {
	$1
} = this.state;$0
endsnippet

snippet props "React Component props"
const {
	$1
} = this.props;$0
endsnippet

snippet rdp "React:defaultProps"
static defaultProps = {
	${VISUAL}$0
}
endsnippet

snippet gds "React:getDerivedStateFromProps"
static getDerivedStateFromProps(props, state) {
	${VISUAL}$1
}$0
endsnippet

snippet gss "React:getSnapshotBeforeUpdate"
getSnapshotBeforeUpdate(prevProps, prevState) {
	${VISUAL}$1
}$0
endsnippet

snippet cdm "React:componentDidMount"
componentDidMount() {
	${VISUAL}$1
}$0
endsnippet

snippet cdu "React:componentDidUpdate"
componentDidUpdate(prevProps, prevState) {
	${VISUAL}$1
}$0
endsnippet

snippet cwu "React:componentWillUnmount"
componentWillUnmount() {
	${VISUAL}$1
}$0
endsnippet

snippet scu "React:shouldComponentUpdate"
shouldComponentUpdate(nextProps, nextState) {
	${VISUAL}$1
}$0
endsnippet

#############
#  GraphQL  #
#############

snippet gql "GraphQL Schema"
gql\`
	${VISUAL}$0
\`;
endsnippet

##########
#  Test  #
##########

snippet desc "describe('test', () => {})" b
describe('${1:test}', () => {
	${VISUAL}$2
})$0
endsnippet

snippet it "it('should do someting', () => {})" b
it('${1:should do something}', () => {
	${VISUAL}$2
})$0
endsnippet
